/*! @file utils.h
 *        @brief Utility functions used for this benchmark
*/

/** @fn print_input_options()
 *     @brief : print user options
*/             
void print_input_options()
{
		printf("\n MAT A FILE       : %s", input_options.mat_A_file);
	if(SOLVER_BENCHMARK)
	{
		printf("\n TOLERANCE        : %lf", input_options.tolerance);
		printf("\n MAX ITERATIONS   : %ld", input_options.max_iterations);
		printf("\n RESTART @        : %d", input_options.restart);
		printf("\n MONITOR TYPE     : %d", input_options.is_verbose);
		printf("\n SOLUTION VECTOR  : %s", input_options.vec_b_file);
	}
}

/** @fn parse_cmd_args
 *     @brief : Take user input options
*/             
void parse_cmd_args(int argc, char **argv)
{
	/* read matrix market file */
	strcpy ( input_options.mat_A_file, argv[1] );

	/* other options only if we are benchamrking solver performance */
	if( SOLVER_BENCHMARK)
	{
		input_options.tolerance = atof (argv[2] );
		input_options.max_iterations = atoi(argv[3]);
		input_options.restart = atoi(argv[4]);

		/* do we want to monitor norm every iterations */
		if( strcmp( argv[5], "true" ) == 0 )
			input_options.is_verbose = 1;
		else
			input_options.is_verbose = 0;

		/* if user has provided solution vector, load it from file */
		if( argc == 7 )
		{
			strcpy ( input_options.vec_b_file, argv[6] );
			input_options.load_b_from_file = 1;
			is_b_setup = 1;

			/* Read matrix market file for solution vector on CPU as well as GPU*/
			cusp::io::read_matrix_market_file(b,      input_options.vec_b_file);
			cusp::io::read_matrix_market_file(b_host, input_options.vec_b_file);
		}
		else
		{
			/*otherwise we will compute exact solution at run time */
			is_b_setup = 0;
			input_options.load_b_from_file = 0;
		}
	}
}


/** @fn setup_A()
 *     @brief : Reads Matrix A from matrix market file !
*/       
void setup_A()
{
	printf("\nREADING MATRIX A FROM MATRIX MARKET FILE : ...  ");
	fflush(stdout);
	cusp::io::read_matrix_market_file(A_Host, input_options.mat_A_file);
	printf(" DONE !");
	fflush(stdout);
}


/** @fn setup_b()
 *     @brief : Set RHS i.e. vector b. Either from market matrix file or random solution
*/             
void setup_b(int num_rows)
{
	/* If b is not already setup */
	if( is_b_setup == 0)
	{
		/* if user has provided matrix market file for solution vector */
		if( input_options.load_b_from_file == 1)
		{
			is_b_setup = 1;
	                cusp::io::read_matrix_market_file(b, input_options.vec_b_file);
			printf("\nSETTING VEC B FROM MATRIX MARKET FILE ! ");
		}
		else
		{	/* otherwise calculate exact solution by setting RHS to 1.0 */
				
			/* now allocate appropriate memory for host and device vectors */
			b.resize(num_rows);
			b_host.resize(num_rows);
			x_host.resize(num_rows);

			/* Fill X vector with 1.0 */
			thrust::fill(x.begin(), x.end(), float(1) );
			thrust::fill(x_host.begin(), x_host.end(), float(1) );

			/*Now calculate RHS i.e. b */
			cusp::multiply(A_Host, x_host, b_host);
			b = b_host;

			/* Now set solution vector i.e. x with 0 */
			thrust::fill(x.begin(), x.end(), float(0) );
			thrust::fill(x_host.begin(), x_host.end(), float(0) );

			is_b_setup = 1;
		}
	}
	else
		printf("\n B IS ALREADY SETUP ! ");
}
